/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd.sessioner;

import java.util.ArrayList;
import java.util.List;

import org.zhiqim.httpd.HttpContext;
import org.zhiqim.httpd.HttpSessionManager;
import org.zhiqim.httpd.model.HttpDomainPortPath;
import org.zhiqim.kernel.model.codes.MD5;
import org.zhiqim.kernel.util.Lists;
import org.zhiqim.kernel.util.Validates;

/**
 * Hash会话管理器，通过HashMap对会话进行管理
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public abstract class AbsSessionManager implements HttpSessionManager
{
    protected HttpContext context;
    protected String sessionIdMark;
    
    private List<String> sessionMustList;
    private List<String> sessionNotList;
    
    public AbsSessionManager()
    {
        sessionMustList = new ArrayList<>();
        sessionNotList = new ArrayList<>(); 
    }
    
    /**************************************************************************************/
    //上下文环境关联
    /**************************************************************************************/
    
    @Override /** 获取上下文环境对象 */
    public HttpContext getContext()
    {
        return context;
    }
    
    @Override /** 设置上下文环境对象 */
    public void setContext(HttpContext context)
    {
        this.context = context;
    }
    
    /**************************************************************************************/
    //设置&判断会话编号标记
    /**************************************************************************************/
    
    @Override /** 设置会话编号标记 */
    public void setSessionIdMark(String sessionIdMark)
    {
        if (Validates.isEmptyBlank(sessionIdMark))
            return;
        
        //有设置的，取设置值
        this.sessionIdMark = MD5.encodeUTF8(sessionIdMark).substring(8, 24);
    }
    
    @Override /** 判断是否会话编号标记 */
    public boolean chkSessionIdMark(String mark, HttpDomainPortPath domainPortPath)
    {
        return mark.equals(sessionIdMark!=null?sessionIdMark:domainPortPath.buildSessionIdMark());
    }
    
    /**************************************************************************************/
    //设置&判断(必须&无需)会话标志
    /**************************************************************************************/
    
    @Override /** 设置会话必需 */
    public void setSessionMust(String sessionMust)
    {
        if (Validates.isEmptyBlank(sessionMust))
            return;
        
        List<String> mustList = Lists.toStringList(sessionMust);
        for (String must : mustList)
        {
            if (Validates.isEmpty(must))
                continue;
            
            if (sessionMustList.contains(must))
                return;
            
            sessionMustList.add(must);
        }
    }
    
    @Override /** 设置会话无需 */
    public void setSessionNot(String sessionNot)
    {
        if (Validates.isEmptyBlank(sessionNot))
            return;
        
        List<String> mustList = Lists.toStringList(sessionNot);
        for (String must : mustList)
        {
            if (Validates.isEmpty(must))
                continue;
            
            if (sessionNotList.contains(must))
                return;
            
            sessionNotList.add(must);
        }
    }
    
    @Override /** 判断是否需要会话 */
    public boolean needSession(String path)
    {
        for (String must : sessionMustList)
        {//1.在必须中需要会话
            if (Validates.isMatch(path, must))
                return true;
        }
        
        for (String not : sessionNotList)
        {//2.在无需中不要会话
            if (Validates.isMatch(path, not))
                return false;
        }
        
        //3.未注明的都需要会话，框架内的不需要会话的，统一使用HttpEntity
        return true;
    }
}
